package stu.kurs.services.impl;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import stu.kurs.domain.User;
import stu.kurs.exceptions.ServiceException;
import stu.kurs.services.IUserService;

@Stateless(name="UserService")
public class UserService extends GenericService<User> implements IUserService{
	
	public UserService(){
		super(User.class);
	}
	
	public User findByEmail(String email) throws ServiceException{
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<User> cq = cb.createQuery(User.class);
		Root<User> r = cq.from(User.class);
		cq.where(cb.equal(r.get("email"), email));
		TypedQuery<User> q = em.createQuery(cq); 
		User user = null;
		try{
			user = q.getSingleResult();
		}
		catch (NoResultException e){
			return null;
		}
		catch (Exception e){
			throw new ServiceException();
		}
		return user;
	}
	
	public String getMD5(String str){
        MessageDigest m = null;
		try {
			m = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
        m.update(str.getBytes(),0,str.length());
        return new BigInteger(1,m.digest()).toString(16);
	}
	
	public boolean changePassword(Integer id, String oldPass, String newPass) throws ServiceException{
		User u = null; 
		u =	findById(id);
		if (u==null) return false;
		if (newPass==null) return false;
		if (newPass.equals("")) return false; 		
		if (getMD5(oldPass).equals(u.getPassword())){
			u.setPassword(getMD5(newPass));
			save(u);
			return true;
		}
		else return false;
	}

	public void changeLevel(Integer id, Integer level) throws ServiceException{
		User u = findById(id);
		u.setLevel(level);
		save(u);
	}

	@Override
	public List<User> getAllUser()	throws ServiceException {
		List<User> result = null;
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<User> cq = cb.createQuery(User.class);
		Root<User> user = cq.from(User.class);
		cq.orderBy(cb.asc(user.get("email")));
		cq.orderBy(cb.asc(user.get("level")));
		TypedQuery<User> q = em.createQuery(cq); 
		try{
			result = q.getResultList();
		}
		catch (Exception e){
			throw new ServiceException(e);
		} 
		return result;
	}

	@Override
	public List<User> getAllByLevel(Integer level) throws ServiceException {
		List<User> result = null;
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<User> cq =cb.createQuery(User.class);
		Root<User> user = cq.from(User.class);
		cq.where(cb.and(cb.equal(user.get("level"), level)));
		cq.orderBy(cb.asc(user.get("email")));
		TypedQuery<User> q = em.createQuery(cq); 
		try{
			result = q.getResultList();
		}
		catch (Exception e){
			throw new ServiceException(e);
		} 
		return result;
	}


}
